import matplotlib.pyplot as plt
import numpy as np
from random import choice
import plotly.express as px

# RandomWalk 类
class RandomWalk:
    """A class to generate random walks."""
    def __init__(self, num_points=5000):
        """Initialize attributes of a walk."""
        self.num_points = num_points
        # All walks start at (0, 0).
        self.x_values = [0]
        self.y_values = [0]

    def fill_walk(self):
        """Calculate all the points in the walk."""
        # Keep taking steps until the walk reaches the desired length.
        while len(self.x_values) < self.num_points:
            # Decide which direction to go, and how far to go.
            x_direction = choice([1, -1])
            x_distance = choice([0, 1, 2, 3, 4])
            x_step = x_direction * x_distance
            y_direction = choice([1, -1])
            y_distance = choice([0, 1, 2, 3, 4])
            y_step = y_direction * y_distance
            
            # Reject moves that go nowhere.
            if x_step == 0 and y_step == 0:
                continue
            
            # Calculate the new position.
            x = self.x_values[-1] + x_step
            y = self.y_values[-1] + y_step
            self.x_values.append(x)
            self.y_values.append(y)

# 使用RandomWalk类生成随机游走数据并绘制图形
def plot_random_walk_classic():
    rw = RandomWalk(50000)
    rw.fill_walk()
    
    # 将所有的点都绘制出来
    plt.style.use('classic')
    fig, ax = plt.subplots(figsize=(15, 9))
    point_numbers = range(rw.num_points)
    ax.scatter(rw.x_values, rw.y_values, c=point_numbers, cmap=plt.cm.Blues, edgecolors='none', s=1)
    ax.set_aspect('equal')
    
    # 突出起点和终点
    ax.scatter(0, 0, c='green', edgecolors='none', s=100)
    ax.scatter(rw.x_values[-1], rw.y_values[-1], c='red', edgecolors='none', s=100)
    
   # 隐藏坐标轴
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
    plt.show()

# 使用Numpy实现随机游走并绘制图形
def plot_random_walk_numpy():
    num_steps = 1000
    # Generate random step distances in x and y directions
    step_distances = np.random.uniform(-4, 4, size=(num_steps, 2))
    # Calculate cumulative sum of step distances
    positions = np.cumsum(step_distances, axis=0)
    
    # Extract x and y coordinates
    x = positions[:, 0]
    y = positions[:, 1]
    
    # Calculate color map based on number of steps
    colors = np.arange(num_steps)
    
    # Plot the random walk
    plt.figure(figsize=(8, 6))
    plt.scatter(x, y, c=colors, cmap='Blues', linewidths=0.5, alpha=0.7)
    plt.scatter(0, 0, color='red', marker='o', label='Starting Point')
    plt.scatter(x[-1], y[-1], color='green', marker='o', label='Ending Point')
    plt.xlabel('X')
    plt.ylabel('Y')
    plt.title('Two-Dimensional Random Walk')
    plt.legend()
    plt.grid(True)
    plt.show()

# 执行函数以生成和绘制随机游走图形
if __name__ == "__main__":
    plot_random_walk_classic()  # 绘制经典样式的随机游走图
    plot_random_walk_numpy()    # 使用Numpy绘制随机游走图
 